OPC Studio User's Guide and Reference
Isolated Clients and Subscribers
Client and Subscriber Development > Development Fundamentals > Components and Objects > Computational Objects > Isolated Clients and Subscribers

Normally, instances of a client or subscriber object (such as EasyDAClient, EasyAEClient, EasyUAClient) act commonly, sharing the same connections to the target OPC servers (or to the message-oriented middleware, in case of PubSub), and also many common parameters. This way, you can create a large number of these instances and work with them in an easy way, without having to worry about negative effects on the target. If, for example, you create two instances of an EasyDAClient object, and subscribe to some OPC items in each of these instances, only one connection will be created to the OPC server.

This approach works well for most applications, and it allows easy coding in scenarios such as Web development, where each page request may require OPC operations, and the requests may be coming in quick succession and in large numbers, and even processed in parallel.

In some cases, however, you may want to have a dedicated connection to the OPC server, or have more control over the parameters of the connection. In such case, you can set the Isolated property of the EasyXXClient or EasyXXSubscriber object to ‘true’. By doing so, operations invoked on this instance of the client object will work with their own connection to the target OPC server, or message-oriented middleware. We say that the client (subscriber) object is isolated.

If you create more such isolated client objects, each of them will work with its own connection. Obviously you need to be more careful with this approach, in order to keep the load on the target OPC server in reasonable limits.

Examples

// This example shows how to create and use two isolated client objects, resulting in two separate connections to the target
// OPC DA server.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

using System;
using System.Diagnostics;
using System.Threading;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    class Isolated
    {
        public static void Main1()
        {
            // Instantiate the client objects and make them isolated
            var client1 = new EasyDAClient { Isolated = true };
            var client2 = new EasyDAClient { Isolated = true };

            // The callback is a local method the displays the value
            void ItemChangedCallback(object sender, EasyDAItemChangedEventArgs eventArgs)
            {
                Debug.Assert(!(eventArgs is null));

                string displayPrefix = $"[{eventArgs.Arguments.State}]";
                if (eventArgs.Succeeded)
                {
                    Debug.Assert(!(eventArgs.Vtq is null));
                    Console.WriteLine($"{displayPrefix} {eventArgs.Vtq}");
                }
                else
                    Console.WriteLine($"{displayPrefix} *** Failure: {eventArgs.ErrorMessageBrief}");
            }

            Console.WriteLine("Subscribing...");
            client1.SubscribeItem("", "OPCLabs.KitServer.2", "Simulation.Random", 1000, ItemChangedCallback, state: 1);
            client2.SubscribeItem("", "OPCLabs.KitServer.2", "Simulation.Random", 1000, ItemChangedCallback, state: 2);

            Console.WriteLine("Processing item changed events for 10 seconds...");
            Thread.Sleep(10 * 1000);

            Console.WriteLine("Unsubscribing...");
            client1.UnsubscribeAllItems();
            client2.UnsubscribeAllItems();

            Console.WriteLine("Waiting for 2 seconds...");
            Thread.Sleep(2 * 1000);
        }
    }
}
# This example shows how to create and use two isolated client objects, resulting in two separate connections to the
# target OPC DA server.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from OpcLabs.EasyOpc.DataAccess import *


# Item changed event handler
def itemChangedCallback(sender, eventArgs):
    assert eventArgs is not None
    displayPrefix = '[{}]'.format(eventArgs.Arguments.State)
    if eventArgs.Succeeded:
        assert eventArgs.Vtq is not None
        print(displayPrefix + ' ' + eventArgs.Vtq.ToString() + '\n', end='')
    else:
        print(displayPrefix + ' *** Failure: ' + eventArgs.ErrorMessageBrief + '\n', end='')


# Instantiate the client objects and make them isolated.
client1 = EasyDAClient()
client1.Isolated = True
client2 = EasyDAClient()
client2.Isolated = True

print('Subscribing item changes...')
IEasyDAClientExtension.SubscribeItem(client1,
                                     '', 'OPCLabs.KitServer.2', 'Simulation.Random', 1000,
                                     EasyDAItemChangedEventHandler(itemChangedCallback), 1)
IEasyDAClientExtension.SubscribeItem(client2,
                                     '', 'OPCLabs.KitServer.2', 'Simulation.Random', 1000,
                                     EasyDAItemChangedEventHandler(itemChangedCallback), 2)

print('Processing item change notifications for 10 seconds...')
time.sleep(10)

print('Unsubscribing all items...')
client1.UnsubscribeAllItems()
client2.UnsubscribeAllItems()

print('Waiting for 2 seconds...')
time.sleep(2)

print('Finished.')
' This example shows how to create and use two isolated client objects, resulting in two separate connections to the target
' OPC DA server.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.OperationModel

Namespace DataAccess._EasyDAClient
    Partial Friend Class Isolated
        Shared Sub Main1()
            ' Instantiate the client objects and make them isolated
            Dim client1 As New EasyDAClient() With {.Isolated = True}
            Dim client2 As New EasyDAClient() With {.Isolated = True}

            ' The callback is a local method the displays the value
            Dim ItemChagedCallback = Sub(sender As Object, eventArgs As EasyDAItemChangedEventArgs)
                                         Debug.Assert(eventArgs IsNot Nothing)

                                         Dim displayPrefix As String = $"[{eventArgs.Arguments.State}]"
                                         If eventArgs.Succeeded Then
                                             Debug.Assert(eventArgs.Vtq IsNot Nothing)
                                             Console.WriteLine($"{displayPrefix} {eventArgs.Vtq}")
                                         Else
                                             Console.WriteLine($"{displayPrefix} *** Failure: {eventArgs.ErrorMessageBrief}")
                                         End If
                                     End Sub

            Console.WriteLine("Subscribing...")
            client1.SubscribeItem("", "OPCLabs.KitServer.2", "Simulation.Random", 1000, ItemChagedCallback, state:=1)
            client2.SubscribeItem("", "OPCLabs.KitServer.2", "Simulation.Random", 1000, ItemChagedCallback, state:=2)

            Console.WriteLine("Processing item changed events for 10 seconds...")
            Threading.Thread.Sleep(10 * 1000)

            Console.WriteLine("Unsubscribing...")
            client1.UnsubscribeAllItems()
            client2.UnsubscribeAllItems()

            Console.WriteLine("Waiting for 2 seconds...")
            Threading.Thread.Sleep(2 * 1000)
        End Sub
    End Class
End Namespace
// This example shows how to create and use two isolated client objects, resulting in two separate connections to the target
// OPC UA server.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

using System;
using System.Diagnostics;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples._EasyUAClient
{
    class Isolated
    {
        public static void Main1()
        {
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            // or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            // Instantiate the client objects and make them isolated
            var client1 = new EasyUAClient { Isolated = true };
            var client2 = new EasyUAClient { Isolated = true };

            // The callback is a local method the displays the value
            void DataChangeCallback(object sender, EasyUADataChangeNotificationEventArgs eventArgs)
            {
                Debug.Assert(!(eventArgs is null));

                string displayPrefix = $"[{eventArgs.Arguments.State}]";
                if (eventArgs.Succeeded)
                {
                    Debug.Assert(!(eventArgs.AttributeData is null));
                    Console.WriteLine($"{displayPrefix} {eventArgs.AttributeData}");
                }
                else
                    Console.WriteLine($"{displayPrefix} *** Failure: {eventArgs.ErrorMessageBrief}");
            }

            Console.WriteLine("Subscribing...");
            client1.SubscribeDataChange(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000, 
                DataChangeCallback, state: 1);
            client2.SubscribeDataChange(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000,
                DataChangeCallback, state: 2);

            Console.WriteLine("Processing data change events for 10 seconds...");
            System.Threading.Thread.Sleep(10 * 1000);

            Console.WriteLine("Unsubscribing...");
            client1.UnsubscribeAllMonitoredItems();
            client2.UnsubscribeAllMonitoredItems();

            Console.WriteLine("Waiting for 2 seconds...");
            System.Threading.Thread.Sleep(2 * 1000);
        }
    }
}
# This example shows how to create and use two isolated client objects, resulting in two separate connections to the
# target OPC UA server.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# The callback is a regular method the displays the value.
def dataChangeCallback(sender, eventArgs):
    displayPrefix = '[{}]'.format(eventArgs.Arguments.State)
    if eventArgs.Succeeded:
        assert eventArgs.AttributeData is not None
        print(displayPrefix + ' Value: ' + '{}'.format(eventArgs.AttributeData.Value) + '\n', end='')
    else:
        print(displayPrefix + ' *** Failure: ' + eventArgs.ErrorMessageBrief + '\n', end='')


endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer')
# or 'http://opcua.demo-this.com:51211/UA/SampleServer' (currently not supported)
# or 'https://opcua.demo-this.com:51212/UA/SampleServer/'

# Instantiate the client objects and make them isolated.
client1 = EasyUAClient()
client1.Isolated = True
client2 = EasyUAClient()
client2.Isolated = True

print('Subscribing...')
IEasyUAClientExtension.SubscribeDataChange(client1,
    endpointDescriptor,
    UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
    1000,
    EasyUADataChangeNotificationEventHandler(dataChangeCallback),
    1)  # state
IEasyUAClientExtension.SubscribeDataChange(client2,
    endpointDescriptor,
    UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
    1000,
    EasyUADataChangeNotificationEventHandler(dataChangeCallback),
    2)  # state

print('Processing data change events for 10 seconds...')
time.sleep(10)

print('Unsubscribing...')
client1.UnsubscribeAllMonitoredItems()
client2.UnsubscribeAllMonitoredItems()

print('Waiting for 2 seconds...')
time.sleep(2)

print('Finished.')
' This example shows how to create and use two isolated client objects, resulting in two separate connections to the target
' OPC UA server.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

Imports System.Windows.Forms.AxHost
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace _EasyUAClient
    Partial Class Isolated
        Public Shared Sub Main1()

            ' Define which server we will work with.
            Dim endpointDescriptor As UAEndpointDescriptor =
                    "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
            ' or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            ' or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            ' Instantiate the client objects and make them isolated
            Dim client1 = New EasyUAClient() With {.Isolated = True}
            Dim client2 = New EasyUAClient() With {.Isolated = True}

            ' The callback is a local method the displays the value
            Dim dataChangeCallback = Sub(ByVal sender As Object, ByVal eventArgs As EasyUADataChangeNotificationEventArgs)
                                         Debug.Assert(eventArgs IsNot Nothing)

                                         Dim displayPrefix As String = $"[{eventArgs.Arguments.State}]"
                                         If eventArgs.Succeeded Then
                                             Debug.Assert(eventArgs.AttributeData IsNot Nothing)
                                             Console.WriteLine($"{displayPrefix} {eventArgs.AttributeData}")
                                         Else
                                             Console.WriteLine($"{displayPrefix} *** Failure: {eventArgs.ErrorMessageBrief}")
                                         End If
                                     End Sub

            Console.WriteLine("Subscribing...")
            client1.SubscribeDataChange(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000,
                dataChangeCallback, state:=1)
            client2.SubscribeDataChange(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000,
                dataChangeCallback, state:=2)

            Console.WriteLine("Processing data change events for 10 seconds...")
            Threading.Thread.Sleep(10 * 1000)

            Console.WriteLine("Unsubscribing...")
            client1.UnsubscribeAllMonitoredItems()
            client2.UnsubscribeAllMonitoredItems()

            Console.WriteLine("Waiting for 2 seconds...")
            Threading.Thread.Sleep(2 * 1000)
        End Sub
    End Class
End Namespace

 

See Also

Examples - OPC Data Access

Examples - OPC Unified Architecture